취약점
CVE_CVE-2025-55182 React2Shell 취약점
작성자 : Heehyeon Yoo|2025-12-16
# React# React2Shell# 취약점# 취약점 분석
1. 개요
- 핵심 요약
서버만 써야 할 내부 설계도(실행 지시서)를 외부 사용자가 위조해서 서버에게 실행하게 만든 사고
1-1. 취약점 개요
| 항목 | 내용 |
|---|---|
| 취약점 명칭 | React2Shell(React Server Components Deserialization RCE) |
| 취약점 유형 | 원격 코드 실행(RCE) |
| 영향도 | Critical(CVSS 스코어 10.0) |
| CVE | CVE-2025-55182 / CVE-2025-66478 |
| 발견 일시 | 2025-12-03 |
1-2. 보안 영향
| 항목 | 내용 |
|---|---|
| 인증 우회 | 가능 |
| 원격 코드 실행 | 가능 |
| 데이터 탈취 | 가능 |
| 서버 장악 | 가능 |
| 확산 위험 | 높음 |
2. 취약점 설명
2-1. CVE-2025-55182
React 19의React Server Components(RSC) / Flight프로토콜 처리 과정에서 발생하는인증 불필요(Pre-auth) 원격 코드 실행(RCE)취약점. 영향 범위가 넓고 익스플로잇이단일 요청(one-request)형태로 알려져 CVSS 10.0로 분류됨- 요약 → RSC가 인증을 거치지 않고 원격으로 코드가 실행되는 매우 위험한 취약점
- 공격자가 인증 없이 RSC에 악성코드가 포함된 HTTP 요청
- 서버가 유효성 검사를 하지 않고 서버 내부 객체 참조/실행 경로 트리거, 공격자가 요청한 코드 실행
- (옵션)코드 실행 결과를 공격자에게 전달
- 해당 취약점은 단일 요청만으로 악용 가능하며, 공격 성공 시 서버 장악, 추가 악성코드 설치, 내부망 이동 등이 가능
2-2. CVE-2025-66478
- 위 이슈의 Next.js(App Router) 다운스트림 영향을 별도 트래킹하기 위해 발급된 CVE. Next.js 측은 이 CVE로
어떤 버전이 영향/수정되었는지를 운영 관점에서 명확히 안내. - 공개 직후부터 광범위한 악용(스캐닝/침투)가 관측되고, 국가 단위/범죄 단체 단위의 블랙 해커 그룹이 가세한 것으로 보고됨
3. 영향 범위
- React 19(RSC)(CVE-2025-55182)
- react-server-dom-webpack 19.0 / 19.1.0 / 19.1.1 / 19.2.0
- react-server-dom-parcel 19.0 / 19.1.0 / 19.1.1 / 19.2.0
- react-server-dom-turbopack 19.0 / 19.1.0 / 19.1.1 / 19.2.0
- Next.js(CVE-2025-66478)
- Next.js 15.x, 16.x
- 14.3.0-canary.77 이상(카나리)
- App Router에서 RSC를 쓰는 구성이
4. 공격 시나리오
- 공격자는 RSC/Server Action 엔드포인트로 악의적 요청 전송
- 서버는 해당 요청을 Flight 프로토콜로 역직렬화
- 내부 실행 객체가 외부 입력으로부터 생성/참조됨
- 서버 실행 흐름이 변조되어 명령 실행 발생
- 서버 권한 탈취 또는 악성 페이로드 설치
5. POC
5-1. POC 과정
- https://github.com/msanft/CVE-2025-55182.git 통해 CVE Clone, bun.lock 있지만 도커 사용 목적이라 불필요한 설정은 안 하는 것이 좋겠다고 판단, Node.js+npm 실행으로 진행 결정

- Dockerfile 생성하고 빌드, 실행, 접속 확인




- 서버 외부에서
poc.py코드 실행, 서버 내부 실행 컨텍스트가 외부 입력에 의해 노출됨

5-2. POC 요약
- 전체 흐름
poc.py: HTTP POST 요청, 헤더를 RSC 요청으로 위장, 바디에Flight chunk 데이터포함하여 전송 → 이chunk는 서로를 참조하며 리액트 전용 문법을 사용하고, 서버가 디코딩하며실행 흐름을 재구성- 서버 : RSC 요청으로 인식 → Flight 디코더로 넘김
- Filght 디코더 : 데이터를 서버가 만든 데이터로 인식 ← 취약점 포인트
- Flight 응답으로 직렬화해서 돌려줌
- 서버 내부 흐름
- RSC 실행 파이프라인 진입
- 내부 객체/thenable/에러 처리 로직 실행
redirect()관련 경로로 떨어짐NEXT_REDIRECT에러 생성- 에러 객체에 서버 런타임 컨텍스트(
uid=0등) 포함 - Flight 응답으로 직렬화해서 돌려줌
- 주의 사항 및 판단 결과
- 이 공격은 임의 명령 실행이나 쉘 실행의 개념이 아님
- 서버 내부 함수 실행/서버 내부 객체 생성/서버 런타임 정보 접근 등 외부 입력으로 내부 실행 경로를 트리거한 것
- 즉, 외부 입력 → 내부 코드 실행 → 내부 상태가 응답으로 새어나옴
- 최종 요약
- poc.py는 React 서버가 내부적으로만 사용해야 할 ‘실행 구조 데이터(Flight)’를 외부에서 위조해 보냈고, 서버는 그걸 믿고 내부 코드를 실제로 실행해버렸다.
- PoC 응답에 포함된
NEXT_REDIRECT내부 예외와 서버 런타임 컨텍스트(uid=0) 정보는, 외부에서 조작된 RSC 요청이 서버의 내부 실행 처리 파이프라인에 도달했음을 의미한다. 이는 공격자가 입력 변형을 통해 추가적인 내부 분기 탐색 및 후속 악용 시나리오를 설계할 수 있는 상태에 도달했음을 보여준다.
- 기타 참고 사항
- 공격자가 이 Poc 코드를 사용했을 때 정보를 얻어서 뭘 할 수 있는가?(실제 공격 코드 말고 샘플 예시)
- RSC 서버임을 확인 → 공격 대상 판단 근거
- 입력 값이 파싱 단계에서 차단되지 않고 실행 단계까지 갔다고 판단 → 다음 단계 설계 가치 판단 근거
uid=0(root), gid=0(root정보를 통해 서버가 root 권한으로 동작 중임을 확인 → 후속 공격 시 영향 판단 근거- 입력 변형 실험 → 코드 구조를 바꾸며 익스플로잇 개발 시작
- 에러 차이로 내부 로직 분기 추론 가능 → 오라클 확보
- 대규모 자동화 공격으로 확장
- 다른 내부 객체로 실행 흐름 유도(function, promise, constructor 계열 등)
- 내부 참조 조작, 비정상 객체 타입 생성
- “금고를 연 것은 아니지만 잡힐 걱정 없이 금고 구조를 분석할 수 있는 상태”
- 기타 알아두면 좋은 것
redirect= 서버 실행 흐름을 멈추고클라이언트에게 이동을 지시하는 제어 객체- 실행 파이프라인 깊숙한 곳에서만 생성되므로, 실행 경로 도달 확인용 신호로 적절
function= 실제 서버가 무언가를 실행하는 단위promise, thenable= 비동기 데이터(RSC는 비동기 실행 모델로, 서버 컴포넌트 결과를 promise나 thenable로 처리, 매우 많음), 즉 서버가 나중에 실행할 것을 약속한 작업들constructor= 객체 생성 틀, 어떤 객체가 만들어질지 결정하는 것
- 공격자가 이 Poc 코드를 사용했을 때 정보를 얻어서 뭘 할 수 있는가?(실제 공격 코드 말고 샘플 예시)
6. 대응 및 권고 사항
6-1. 즉각 조치 필요
- React / Next.js 보안 패치 버전으로 업그레이드
- React RSC 19.0.1 / 19.1.2 / 19.2.1
- Next.js 15.0.5 / 15.1.9 / 15.2.6 / 15.3.6 / 15.4.8 / 15.5.7 / 16.0.7
- 패치 후 전체 빌드 및 재배포
- 노출된 서비스의 시크릿 키 재발급
6-2. 장기 대응 방안
- RSC 입력 검증 강화
- Server Action 접근 제어
- 비정상 요청 로깅 및 탐지 정책 적용
7. 참고 자료
- PoC Code: https://github.com/msanft/CVE-2025-55182
- datadog: https://securitylabs.datadoghq.com/ar...
- microsoft: https://techcommunity.microsoft.com/b...
- aws: https://aws.amazon.com/blogs/security...
- google cloud: https://cloud.google.com/blog/product...
- react2shell: https://github.com/freeqaz/react2shell
- react 패치 PR: https://github.com/facebook/react/pul...
+ 상세 흐름 이해해보기
1. RSC는 왜 도입되었는가
- 기존 웹 애플리케이션은 크게 클라이언트 중심 방식/서버 중심 방식이었음

- 서버에서 데이터를 보내면 브라우저가 JS/DOM을 다운로드하고 직접 조립, 출력
- 클라이언트 부담 ↑, 서버 자원(DB/API)에 접근 불가

- 클라이언트 부담 ↑, 서버 자원(DB/API)에 접근 불가
- 서버가 완전히 조립된 페이지를 보내면 브라우저는 출력만
- 서버 부담 ↑, 인터랙션은 클라이언트 JS가 부담
- 이를 해결하기 위해 RSC 도입

- 화면 구성 부품 중 서버에서 처리하기 더 적절한 것만 서버에서 실행
- 서버는 계산과 판단을 담당하고, 브라우저(React)는 조립과 상호작용을 담당
- → 서버는 구조화된 실행 결과를 보내고 브라우저(React)가 이것을 받아 조립한다
- Flight = 구조화된 실행 결과로, 화면의 모양이 아니라 화면을 만드는 방법을 담은 데이터(화면 설계도+데이터 묶음)
- RSC의 암묵적 전제
- Flight는 서버에서만 생성되는, 사람이 만질 수 없는 데이터이므로 신뢰할 수 있는 데이터
- ex) 사용자 입력 데이터 = 고객의 신청서 / Flight 데이터 = 회사 내부의 업무 처리 지시서 → 외부인 접근 X
- 성능, 보안, 구조적으로 매우 좋음
- Flight는 서버에서만 생성되는, 사람이 만질 수 없는 데이터이므로 신뢰할 수 있는 데이터
요약하자면, RSC(React Server Components)는 서버에서 실행된 컴포넌트의 결과와 실행 구조를 Flight라는 내부 전용 포맷으로 전달하는 구조다. Flight는 단순 데이터가 아니라 서버 실행 흐름을 설명하는 설계도에 가깝기 때문에, React는 이를
외부에서 절대 생성되지 않는 내부 데이터라고 가정하고 설계했다.
2. 어떻게 신뢰가 붕괴되었는가
- 신뢰 경계 개념과 Flight
- 신뢰 경계란, 이 지점부터 들어오는 데이터는 믿지 않는다고 정한 선
- 클라이언트 브라우저 → 서버 : 신뢰 X
- 서버 내부 메모리 → 서버 코드 : 신뢰 O
- DB 결과 → 서버 코드 : 조건부 신뢰 O
- 이 경계가 명확하면 입력 검증의 지점이 명확해지고 내부 로직이 단순해짐
- 즉, Flight는 서버 내부에서 생성되어 외부로 나가기만 하는 데이터라는 전제 하에
- Flight는 검증 필요가 없으며, 복잡한 보안 로직도 불필요하여 성능, 구조가 매우 좋아짐
- 신뢰 경계란, 이 지점부터 들어오는 데이터는 믿지 않는다고 정한 선
- 클라이언트 → 서버가 정말 신뢰 X인가?
- 서버 액션, 인터랙션 후 서버 재실행, 스트리밍 업데이트 등 클라이언트 → 서버로 보내는 요청 존재
java 외부 입력 HTTP 요청 [클라이언트] -> RSC 요청(HTTP) -> [서버] -> RSC 처리 파이프라인 -> Flight 생성
- 이때 요청과 내부 메시지가 같은 파이프라인으로 작동
- 즉, React 서버가 외부에서 들어온 요청을 내부에서 생성한 Flight와 같은 처리 로직으로 다룸
java [외부 입력 HTTP 요청] -> Flight 디코더 -> [내부 실행 로직]
- 이때 Flight 디코더가 ‘내부 데이터’를 전제로 설계됨
- 그러나 실제로는 외부 사용자가 보낸 데이터가 그대로 들어올 수 있었음
- 이렇게 설계된 이유는?
- 현실적 낙관 : Flight는 일반 사용자가 알기에는 복잡한 데이터 포맷, 직접 만들어 보내기 힘들다는 생각
- 내부 프로토콜이라는 착각 : REST API도 아니고, 공개 포맷도 아니고, 외부 연동용도 아니니 사실상 내부 네트워크라고 인식
- 이렇게 설계된 이유는?
- 보안 관점으로,
HTTP로 들어온 순간 해당 데이터는 공격자가 통제할 수 있는 데이터라는 원칙이 RSC 설계와 충돌- 즉, 검증 대상이 아니라고 설계 단계에서 판단해버린 것 → 검증 개념 자체가 존재하지 않는 설계
3. 원격 코드 실행(RCE)으로 이어진 주요 문제
- RSC의 입력 처리 성격의 문제
- 일반적인 서버 입력의 경우 외부 입력은 파라미터 즉, 문자열이나 숫자, JSON이며 검증 실패 시 요청이 거부되고, 성공해도 데이터로만 사용됨
- 데이터 오류나, 권한 문제, 정보 노출 수준의 취약점
- JSON → 객체로 값을 복원하는 역직렬화
- RSC의 경우 외부 입력이 단순 데이터가 아닌
서버가 무엇을 실행할지 결정하는 지시 정보로 취급됨- 역직렬화가 값만 복원하는게 아님
- 실행 구조를 복원하고 컴포넌트 트리를 재구성, 모듈 참조 연결, 서버 액션 호출 경로를 결정
- 즉, Flight의 해석은 서버 내부의 실행 흐름을 재현할 수 있는 단서
- 역직렬화가 값만 복원하는게 아님
- 일반적인 서버 입력의 경우 외부 입력은 파라미터 즉, 문자열이나 숫자, JSON이며 검증 실패 시 요청이 거부되고, 성공해도 데이터로만 사용됨
- 서버가 Flight를 무조건 신뢰하는 문제
- RSC는 이 Flight 데이터를
내부 데이터로 인식하고 모듈 참조 안전, 실행 대상 신뢰, 의도된 함수 호출로 인식 - 이미 검증된 상태라고 가정
- RSC는 이 Flight 데이터를
- Flight의 완결성 문제
- 보통의 RCE를 위해서는 여러 단계와 상태 누적, 인증 우회 등을 거쳐야 함
- 그러나 RCS에서는 Flight 자체가 완결된 실행 지시서로 인식, 상태와 인증, 세션 등의 정보 없이도 실행
- 따라서 단일 요청(one-request)만으로도 RCE가 가능한 중대 취약점이 발생
4. 어떤 방식으로 공격이 가능했는가
- 공격자는
RSC 요청처럼 보이는 요청을 보냄- RSC 요청과 동일한 구조의 HTTP
- Flight 데이터처럼 보이는 페이로드
- 서버는 URL도 정상, 헤더도 정상, RSC 요청 조건도 충족된 것으로 판단
- 이 요청은
브라우저 React가 보낸 RSC 요청이다라고 판단 - 서버가 요청을 Flight 디코딩 단계로 요청을 전달하면 데이터의 내부/외부 검증 X
- 이 요청은
- 공격자는 Flight 데이터를 통해 다음과 같은 정보를 조작
- 서버 모듈 참조/실행 경로/인자로 넘길 값
- 서버 실행 흐름 자체 조작 가능
- Node.js 런타임에서 실행 → 파일 시스템 접근 가능 → OS 명령과 논리적으로 가까움
- 임의 코드 실행, 시스템 명령 실행, 악성 페이로드 설치까지 이어짐
5. 결론
- 단순 원격 코드 취약점이 아닌 프레임워크 레벨의 취약점
- 개발자의 시큐어 코딩으로도 해결 불가
- 보안 책임자나 개발자의 손을 떠난 취약점
- 대응 난이도가 높고, 영향 범위나 파급력이 강하다
- 프레임워크 버그가 아닌 설계 상의 취약점
- Flight 데이터를 무조건 신뢰 가능한 내부 데이터로 취급한 설계 취약점
- 워크어라운드 없이 업그레이드해야 하는 프레임워크 실행 파이프라인 자체의 문제
- 따라서 현재 패치는 Fligt 디코딩 전 입력의 내/외부 검증과 허용 실행 경로를 검증하고 내부 구조를 외부 요청에서 재구성 불가하도록 → 신뢰 경계를 코드 레벨에서 다시 설정
- 생각해야 할 점
- 네트워크를 타는 순간 그게 내부 포맷이든 뭐든 공격 루트라는 관점 필요
- 서버 실행 경로를 담은 데이터는 무조건 위험하다는 인식 필요
- 프레임워크 선택조차 보안 의사결정에 필요하다는 인식 필요
- 공격자 관점
- 내부 데이터도 네트워크를 타면 공격 대상이며
- REST나 GraphQL같은 공개 API만 보지 않고 내부프로토콜과 전용 직렬화 포맷, 서버-클라이언트간 비공개 메시지까지 분석 대상으로 삼음
- 정리하자면, React2Shell은 공격자에게 프레임워크 내부 데이터와 전용 프로토콜 역시 네트워크를 통해 전달되는 이상 공격 표면이 될 수 있음을 확인시켜 주었다. 향후 공격자는 공개 API뿐 아니라 내부 직렬화 포맷과 실행 지시 데이터까지 분석 대상으로 삼을 것이며, 패치 이후 새롭게 형성된 신뢰 가정과 검증 로직을 우회하는 방향으로 공격을 설계할 가능성이 높다.
- 방어자 관점
- 내부 데이터라 안전하다는 표현 지양
- 침투 경로를 그리는 사고방식 필요
- 정리하자면, 본 취약점은 ‘내부 전용 데이터’라는 표현이 보안상 신뢰 근거가 될 수 없음을 보여준다. 외부 입력이 도달할 수 있는 경로가 존재하는 이상, 해당 데이터는 공격자 관점에서 분석·위조 대상이 된다. 향후 유사 사고를 방지하기 위해서는 데이터의 성격이 아니라, 데이터의 이동 경로와 해석 지점을 기준으로 신뢰 경계를 설정하는 보안 사고 방식이 필요하다.
- 추후 체크포인트
- 내부 전용 데이터가 네트워크를 타는지 점검
- 역직렬화가 일어나는 지점 확인